Skip to main content

Application Files

Overview

The Application Files API provides functionality for managing supporting documents and files for applications. This includes uploading files using presigned URLs for secure, direct-to-storage uploads, and deleting files when they are no longer needed. Files are associated with specific document fields as defined in the application configuration.

Upload Application Files

Overview

The Upload Application Files endpoint generates presigned URLs for secure, direct-to-storage file uploads. This two-step process first registers file metadata with the API, then uses the returned presigned URL to upload the actual file directly to cloud storage.

Authentication

This endpoint requires authentication. See API Authentication for detailed requirements and how to obtain credentials.

Endpoint

PUT /api/applications/:applicationId/files

Request Body

Interface Definitions

interface ApplicationAdditionalDocument {
folderId: string;
}

interface ApplicationFileUploadDTO {
fileName: string;
fileSize: number;
fileType: string;
documentField: string;
additionalDocument?: ApplicationAdditionalDocument;
}

interface FileUploadResponse {
statusCode: number;
message: string;
data: ApplicationFileUploadResponseDTO[];
}

interface ApplicationFileUploadResponseDTO {
fileId: string;
folderId: string;
signedUrl: string;
}

Field Descriptions

Request Fields:
  • fileName (required): The original name of the uploaded file
  • fileSize (required): Size of the file in bytes
  • fileType (required): MIME type or file extension of the uploaded file
  • documentField (required): The document field identifier that this file corresponds to (as defined in the application configuration)
  • additionalDocument (optional): Additional document configuration for uploading to custom folders
Response Fields:
  • fileId: Unique identifier for the uploaded file
  • folderId: Identifier of the folder where the file is stored
  • signedUrl: Pre-signed URL for direct file upload to cloud storage

Additional Document Upload Rules

Important Upload Rules

For Additional Document Folders:

  • When uploading to an additional document folder, you MUST include the additionalDocument object in the payload
  • The documentField value MUST be set to 'additionalDocuments'
  • The additionalDocument.folderId should contain the folder ID returned from the Create Additional Documents endpoint

For Standard Document Fields:

  • When uploading to predefined document fields (e.g., 'identificationDocument', 'proofOfAddress'), you MUST NOT include the additionalDocument object in the payload
  • Use only the standard documentField values as defined in your application configuration

Supported File Types

The API accepts various document types commonly used for KYC/AML compliance:

  • Images: .jpg, .jpeg, .png, .gif, .webp
  • Documents: .pdf, .doc, .docx
  • Spreadsheets: .xls, .xlsx, .csv
  • Other: .txt, .rtf

File Size Limits

  • Maximum file size: 10MB per file
  • Maximum total upload size per request: 50MB

Request Examples

Standard Document Field Upload

For uploading to predefined document fields (identificationDocument, proofOfAddress, etc.):

{
"fileName": "passport_john_doe.pdf",
"fileSize": 2048576,
"fileType": "application/pdf",
"documentField": "identificationDocument"
}
Additional Document Folder Upload

For uploading to additional document folders created via the Create Additional Documents endpoint:

{
"fileName": "tax_clearance_certificate.pdf",
"fileSize": 1536000,
"fileType": "application/pdf",
"documentField": "additionalDocuments",
"additionalDocument": {
"folderId": "60d5ecb54f3d2b001f8b4570"
}
}
Multiple File Upload Example
[
{
"fileName": "passport_john_doe.pdf",
"fileSize": 2048576,
"fileType": "application/pdf",
"documentField": "identificationDocument"
},
{
"fileName": "board_resolution.pdf",
"fileSize": 1024000,
"fileType": "application/pdf",
"documentField": "additionalDocuments",
"additionalDocument": {
"folderId": "60d5ecb54f3d2b001f8b4571"
}
}
]

Response Structure

Success Response

{
"statusCode": 200,
"message": "File upload URLs generated successfully",
"data": [
{
"fileId": "60d5ecb54f3d2b001f8b4569",
"folderId": "60d5ecb54f3d2b001f8b4570",
"signedUrl": "https://storage.example.com/bucket/upload?signature=abc123..."
}
]
}

Multiple Files Success Response

{
"statusCode": 200,
"message": "File upload URLs generated successfully",
"data": [
{
"fileId": "60d5ecb54f3d2b001f8b4569",
"folderId": "60d5ecb54f3d2b001f8b4570",
"signedUrl": "https://storage.example.com/bucket/upload?signature=abc123..."
},
{
"fileId": "60d5ecb54f3d2b001f8b456a",
"folderId": "60d5ecb54f3d2b001f8b4571",
"signedUrl": "https://storage.example.com/bucket/upload?signature=def456..."
}
]
}

Delete Application Files

Overview

The Delete Application Files endpoint allows you to remove one or more files associated with an application. This is useful for updating documents or removing files that are no longer needed.

Authentication

This endpoint requires authentication. See API Authentication for detailed requirements and how to obtain credentials.

Endpoint


DELETE /api/applications/:applicationId/files

Request Body

Interface Definitions

interface DeleteApplicationFileDTO {
fileIds: string[];
}

Field Descriptions

  • fileIds (required): Array of file identifiers to be deleted

Request Example

{
"fileIds": ["60d5ecb54f3d2b001f8b4569", "60d5ecb54f3d2b001f8b456a"]
}

Response Structure

Success Response

The API returns a 200 OK status code when files are successfully deleted. No response body is returned.

HTTP/1.1 200 OK

Error Response

{
"statusCode": 400,
"message": "File deletion validation failed",
"errors": [
{
"field": "fileIds",
"message": "At least one file ID is required"
},
{
"field": "fileIds[0]",
"message": "Invalid file ID format"
}
]
}

Create Additional Documents

Overview

The Create Additional Documents endpoint allows you to create custom document categories for an application beyond the standard predefined document fields. This is useful when you need to upload files that don't fit into the existing document structure defined in the application configuration. Before uploading files to these additional document categories, you must first create the document folder through this API.

Authentication

This endpoint requires authentication. See API Authentication for detailed requirements and how to obtain credentials.

Endpoint

POST /api/applications/:id/additional-documents

Request Body

Interface Definitions

interface CreateAdditionalFolderDTO {
name: string;
isRequired: boolean;
}

interface CreateAdditionalFolderResponse {
statusCode: number;
message: string;
data: {
folderId: string;
};
}

Field Descriptions

  • name (required): The name for the additional document folder
  • isRequired (required): Whether this document folder is mandatory for application completion

Request Example

{
"name": "Additional Compliance Documents",
"isRequired": false
}

Multiple Document Folders Example

[
{
"name": "Board Meeting Minutes",
"isRequired": true
},
{
"name": "Insurance Certificates",
"isRequired": false
}
]

Response Structure

Success Response

### Response Structure

#### Success Response

```json
{
"statusCode": 201,
"message": "Additional document folder created successfully",
"data": {
"folderId": "60d5ecb54f3d2b001f8b4570"
}
}

Multiple Folders Success Response

{
"statusCode": 201,
"message": "Additional document folders created successfully",
"data": [
{
"folderId": "60d5ecb54f3d2b001f8b4570"
},
{
"folderId": "60d5ecb54f3d2b001f8b4571"
}
]
}

Error Response

{
"statusCode": 400,
"message": "Additional document folder creation validation failed",
"errors": [
{
"field": "name",
"message": "Folder name is required and must be unique for this application"
},
{
"field": "isRequired",
"message": "isRequired must be a boolean value"
}
]
}

#### Multiple Categories Success Response

```json
{
"statusCode": 201,
"message": "Additional document categories created successfully",
"data": [
{
"documentId": "60d5ecb54f3d2b001f8b4570",
"documentField": "board_meeting_minutes_60d5ecb5",
"documentName": "Board Meeting Minutes",
"documentCategory": "governance",
"isRequired": true,
"allowMultiple": true,
"acceptedFileTypes": ["application/pdf"],
"maxFileSize": 10485760,
"createdAt": "2024-01-15T10:30:00.000Z"
},
{
"documentId": "60d5ecb54f3d2b001f8b4571",
"documentField": "insurance_certificates_60d5ecb5",
"documentName": "Insurance Certificates",
"documentCategory": "insurance",
"isRequired": false,
"allowMultiple": true,
"acceptedFileTypes": [
"application/pdf",
"image/jpeg",
"image/png",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
],
"maxFileSize": 10485760,
"createdAt": "2024-01-15T10:30:00.000Z"
}
]
}

Error Response

{
"statusCode": 400,
"message": "Additional document creation validation failed",
"errors": [
{
"field": "documentName",
"message": "Document name is required and must be unique for this application"
},
{
"field": "maxFileSize",
"message": "Maximum file size cannot exceed 50MB"
}
]
}

Using Additional Documents with File Upload

After creating an additional document folder, you can use the returned folderId to upload files using the standard file upload endpoint:

Step 1: Create Additional Document Folder

// Create additional document folder
const createFolderResponse = await fetch(
'/api/applications/123/additional-documents',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + authToken,
},
body: JSON.stringify({
name: 'Tax Clearance Certificates',
isRequired: true,
}),
}
);

const { data: folderData } = await createFolderResponse.json();
const folderId = folderData.folderId; // e.g., "60d5ecb54f3d2b001f8b4570"

Step 2: Upload Files to Additional Document Folder

// Upload file to the newly created document folder
const fileMetadata = {
fileName: 'tax_clearance_2024.pdf',
fileSize: 1048576,
fileType: 'application/pdf',
documentField: 'additionalDocuments', // Must be 'additionalDocuments' for additional folders
additionalDocument: {
folderId: folderId, // Use the folderId from step 1
},
};

const uploadResponse = await fetch('/api/applications/123/files', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + authToken,
},
body: JSON.stringify(fileMetadata),
});

// Continue with presigned URL upload process...

Example: Standard Document Field Upload

// Upload file to a standard document field (no additionalDocument needed)
const standardFileMetadata = {
fileName: 'passport.pdf',
fileSize: 2048576,
fileType: 'application/pdf',
documentField: 'identificationDocument', // Standard document field
// DO NOT include additionalDocument for standard fields
};

const standardUploadResponse = await fetch('/api/applications/123/files', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + authToken,
},
body: JSON.stringify(standardFileMetadata),
});

Field Validation Requirements

Document Folder Creation Validation

  • name must be unique within the application
  • name must be between 3 and 100 characters
  • isRequired must be a boolean value
  • User must have permissions to create additional document folders for the application

File Upload Validation

For Additional Document Folders:
  • documentField MUST be exactly 'additionalDocuments'
  • additionalDocument object MUST be included in the payload
  • additionalDocument.folderId MUST be a valid folder ID from a previously created additional document folder
  • The specified folder must belong to the application
For Standard Document Fields:
  • documentField MUST be a valid predefined document field (e.g., 'identificationDocument', 'proofOfAddress')
  • additionalDocument object MUST NOT be included in the payload
  • The document field must be defined in the application configuration
Common Validation Rules:
  • fileName is required and must be a non-empty string
  • fileSize is required and must be a positive number
  • fileType is required and must be a valid MIME type
  • File size must not exceed the maximum allowed limit

Usage Restrictions

  • Maximum 20 additional document folders per application
  • Folder names cannot conflict with existing predefined document fields
  • Once created, document folders cannot be deleted if files have been uploaded
  • Required additional document folders must be fulfilled before application submission

Integration Workflow

For Standard Document Fields:

  1. Check Configuration: Use the Get Configuration API to identify required document fields
  2. Upload Files: Upload directly using the predefined documentField values
  3. Validate Completion: Ensure all required standard documents are uploaded
  4. Submit Application: Proceed with application submission

For Additional Document Folders:

  1. Assess Requirements: Determine if additional custom document categories are needed
  2. Create Folders: Use the Create Additional Documents endpoint to create custom folders
  3. Upload Files: Upload using documentField: 'additionalDocuments' with the additionalDocument.folderId
  4. Validate Completion: Ensure all required additional document folders are populated
  5. Submit Application: Proceed with application submission

Combined Workflow:

Applications can use both standard document fields and additional document folders as needed. Simply follow the appropriate payload structure for each upload type.

File Management Guidelines

Presigned URL Security

  • Presigned URLs are time-limited and expire automatically
  • URLs are specific to the intended file and cannot be reused
  • Direct uploads bypass your server, reducing bandwidth usage
  • Cloud storage handles encryption and secure transmission

File Validation

  • File type validation occurs both client-side and server-side
  • File size limits are enforced during upload
  • Malicious file detection is performed on uploaded content
  • Access controls ensure only authorized users can manage files

Best Practices

Upload Workflow

  1. Validate locally: Check file type and size before API call
  2. Request presigned URL: Call the upload endpoint with file metadata
  3. Upload directly: Use presigned URL to upload to cloud storage
  4. Handle errors: Implement retry logic for failed uploads
  5. Confirm completion: Verify upload success before proceeding

Error Handling

async function uploadFileWithRetry(fileMetadata, file, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
// Step 1: Get signed URL
const response = await fetch('/api/applications/123/files', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(fileMetadata),
});

const { data } = await response.json();
const { fileId, folderId, signedUrl } = data[0];

// Step 2: Upload file directly
const uploadResponse = await fetch(signedUrl, {
method: 'PUT',
body: file,
headers: {
'Content-Type': file.type,
},
});

if (uploadResponse.ok) {
return {
success: true,
fileId: fileId,
folderId: folderId,
};
}

throw new Error('Upload failed');
} catch (error) {
console.error(`Upload attempt ${attempt} failed:`, error);
if (attempt === maxRetries) {
throw error;
}
// Wait before retry
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
}
}
}

Deletion Best Practices

  • Always verify file ownership before deletion
  • Consider soft deletion for audit trails
  • Batch delete operations for efficiency
  • Handle partial failures gracefully
  • Log deletion activities for compliance

Usage Examples

Complete Upload Flow

// Complete file upload example
async function uploadApplicationFile(applicationId, file, documentField) {
try {
// Prepare file metadata
const fileMetadata = {
fileName: file.name,
fileSize: file.size,
fileType: file.type,
documentField: documentField,
};

// Step 1: Get presigned URL
const response = await fetch(`/api/applications/${applicationId}/files`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + authToken,
},
body: JSON.stringify(fileMetadata),
});

if (!response.ok) {
throw new Error('Failed to get presigned URL');
}

const { data } = await response.json();
const uploadData = data[0];

// Step 2: Upload file directly to storage
const uploadResponse = await fetch(uploadData.signedUrl, {
method: 'PUT',
body: file,
headers: {
'Content-Type': file.type,
},
});

if (!uploadResponse.ok) {
throw new Error('File upload failed');
}

return {
success: true,
fileId: uploadData.fileId,
folderId: uploadData.folderId,
message: 'File uploaded successfully',
};
} catch (error) {
console.error('Upload error:', error);
return {
success: false,
error: error.message,
};
}
}

File Deletion Example

// Delete multiple files
async function deleteApplicationFiles(applicationId, fileIds) {
try {
const response = await fetch(`/api/applications/${applicationId}/files`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + authToken,
},
body: JSON.stringify({ fileIds }),
});

if (response.ok) {
console.log('Files deleted successfully');
return { success: true };
} else {
const errorData = await response.json();
throw new Error(errorData.message || 'File deletion failed');
}
} catch (error) {
console.error('Deletion error:', error);
throw error;
}
}

Document Field Mapping

The documentField parameter should correspond to the document fields defined in your application configuration. Common document field identifiers include:

Identity Documents

  • identificationDocument - Passport, driver's license, national ID
  • proofOfAddress - Utility bills, bank statements, lease agreements
  • birthCertificate - Birth certificate or equivalent

Company Documents

  • certificateOfIncorporation - Company registration certificate
  • memorandumOfAssociation - Company memorandum and articles
  • boardResolution - Board resolutions and meeting minutes
  • shareRegister - Share register and ownership documents
  • financialStatements - Audited financial statements
  • businessLicense - Business licenses and permits

Additional Documents

  • sourceOfFunds - Documentation proving source of funds
  • bankStatements - Personal or corporate bank statements
  • taxReturns - Tax returns and declarations
  • employmentLetter - Employment verification letters
  • contractAgreements - Business contracts and agreements

Field Validation Requirements

Upload Validation

  • The documentField must be a valid field identifier
  • The document field must be configured in the application template
  • Required document fields must be uploaded before application submission
  • File size must not exceed maximum limits
  • File type must be in the supported formats list

Deletion Validation

  • File IDs must be valid and exist in the system
  • User must have permissions to delete the specified files
  • Files must belong to the specified application
  • Cannot delete files that are required and have no alternatives

Error Handling

Common Upload Errors

  • 400 Bad Request: Invalid file metadata or unsupported file type
  • 401 Unauthorized: Authentication failure
  • 403 Forbidden: Insufficient permissions to upload files
  • 413 Payload Too Large: File size exceeds limits
  • 422 Unprocessable Entity: Invalid document field or application state

Common Deletion Errors

  • 400 Bad Request: Invalid file IDs or empty request
  • 401 Unauthorized: Authentication failure
  • 403 Forbidden: Insufficient permissions to delete files
  • 404 Not Found: One or more files not found
  • 409 Conflict: Cannot delete required files

Presigned URL Errors

  • URL Expired: Presigned URL has expired (15-minute limit)
  • Access Denied: Invalid credentials or permissions
  • Invalid Request: Malformed upload request to cloud storage
Integration Tip

Always validate file types and sizes client-side before requesting presigned URLs to improve user experience and reduce unnecessary API calls.

Security Notice

Presigned URLs expire after 15 minutes for security. If upload fails, request a new presigned URL rather than retrying with an expired URL.

Important

File uploads are direct to cloud storage using presigned URLs. Ensure your application handles the two-step process correctly for reliable file management.